package menu

import (
	"context"
	"go-zero-project/services/user/rpc/internal/mapper"

	"go-zero-project/services/user/rpc/internal/svc"
	"go-zero-project/services/user/rpc/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type NavListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewNavListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NavListLogic {
	return &NavListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *NavListLogic) NavList(in *pb.NavListReq) (*pb.NavListResp, error) {
	// 1.查询用户的所有菜单ID
	allMenuIdArr, err := mapper.NewRoleMapper().QueryAllMenuId(l.svcCtx.DBEngin, in.UserId)
	if err != nil {
		logx.Errorf("query user all menuId from user rpc failed:%", err.Error())
		return nil, err
	}
	// 2.获取所有菜单列表
	menuList, err := l.getAllMenuList(allMenuIdArr)
	if err != nil {
		return nil, err
	}
	return &pb.NavListResp{MenuArr: menuList}, nil

}

func (l *NavListLogic) getAllMenuList(menuIdArr []int64) ([]*pb.MenuInfoResp, error) {
	//查询根菜单列表
	queryListParentArr, err := l.queryListParentId(0, menuIdArr)
	if err != nil {
		return nil, err
	}
	//递归获取子菜单
	menuTreeList, err := l.getMenuTreeList(queryListParentArr, menuIdArr)
	if err != nil {
		return nil, err
	}
	return menuTreeList, err
}

func (l *NavListLogic) queryListParentId(menuId int64, menuIdArr []int64) ([]pb.MenuInfoResp, error) {
	menuEntityArr, err := mapper.NewMenuMapper().QueryListParentId(l.svcCtx.DBEngin, menuId)
	if err != nil {
		logx.Errorf("mapper.NewMenuMapper().QueryListParentId failed:%s", err.Error())
		return nil, err
	}
	var navArr []pb.MenuInfoResp
	if len(menuEntityArr) == 0 {
		return navArr, err
	}
	for _, v := range menuEntityArr {
		if int64Contains(menuIdArr, v.MenuId) {
			navArr = append(navArr, pb.MenuInfoResp{
				MenuId:   v.MenuId,
				ParentId: v.ParentId.Int64,
				Name:     v.Name,
				Url:      v.Url,
				Perms:    v.Perms,
				MenuType: int32(v.Type.Int16),
				Icon:     v.Icon,
				OrderNum: v.OrderNum.Int32,
			})
		}
	}
	return navArr, err
}

func (l *NavListLogic) getMenuTreeList(arr []pb.MenuInfoResp, menuIdArr []int64) ([]*pb.MenuInfoResp, error) {
	var subArr []*pb.MenuInfoResp
	if len(arr) <= 0 {
		return subArr, nil
	}
	for i := 0; i < len(arr); i++ {
		v := pb.MenuInfoResp{
			MenuId:   arr[i].MenuId,
			ParentId: arr[i].ParentId,
			Name:     arr[i].Name,
			Url:      arr[i].Url,
			Perms:    arr[i].Perms,
			MenuType: arr[i].MenuType,
			Icon:     arr[i].Icon,
			OrderNum: arr[i].OrderNum,
			List:     arr[i].List,
		}
		//目录
		if v.MenuType == 0 {
			queryListParentIdArr, err := l.queryListParentId(v.MenuId, menuIdArr)
			if err != nil {
				return nil, err
			}
			menuTreeList, err := l.getMenuTreeList(queryListParentIdArr, menuIdArr)
			if err != nil {
				return nil, err
			}
			v.List = menuTreeList
		}
		subArr = append(subArr, &v)
	}
	return subArr, nil
}

func int64Contains(array []int64, val int64) bool {
	for i := 0; i < len(array); i++ {
		if array[i] == val {
			return true
		}
	}
	return false
}
